import { openNotificationWithIcon } from "utils/comm";
import _isEmnpty from "lodash/isEmpty";

const CheckConnection = (circleBreak, allProcesses, edgesSources, child, orgParent) => {


    let pass = true;
    const { parent, label = '', shape = '', id } = child;

    // 防止死循环
    const count = circleBreak[id] ?? 0;
    if (count > 3) {
        return true;
    } else {
        circleBreak[id] = count + 1;
    }

    if (_isEmnpty(parent) || orgParent !== parent) {
        openNotificationWithIcon("error", "", `检查子流程步骤 ${label} 不能在子流程外面`);
        pass = false;
        return false;
    }

    // const {target = ''} = edgesSources[id] ?? [];

    const sourceList = edgesSources[id] ?? [];
    sourceList.some(item => {
        const { target = '', source = '' } = item;

        const nextChild = allProcesses[target];
        if (_isEmnpty(target) || _isEmnpty(nextChild)) {
            openNotificationWithIcon("error", "", `检查子流程步骤 ${label} 不能直接结束流程`);
            pass = false;
            return true;
        }

        if (_isEmnpty(nextChild.parent) && shape !== 'GroupTaskEnd') {
            openNotificationWithIcon("error", "", `检查子流程步骤 ${label} 不能直接连接外部节点`);
            pass = false;
            return true;
        }

        if (shape === 'GroupTaskEnd' && _isEmnpty(nextChild.parent)) {
            return true;
        }
        if (source !== target && !_isEmnpty(target) && !_isEmnpty(source)) {

            pass = CheckConnection(circleBreak, allProcesses, edgesSources, nextChild, orgParent);

        }
        if (!pass) {
            return true;
        }
    })

    return pass;
}


export const GroupCheck = (nodes = [], edges = [], groups = []) => {

    let pass = true;

    // 检查编码
    const overrideList = [];
    const allProcesses = {};

    const groupStart = [];
    const groupEnd = [];
    nodes.some(item => {
        const { model, id, shape, label = '' } = item;
        const { properties } = model;
        const { overrideid } = properties;
        const isGateway = shape.indexOf('Gateway') !== -1;
        if (_isEmnpty(overrideid) && !isGateway) {
            pass = false;
            openNotificationWithIcon("error", "", `节点 ${label} 编码未填写`);
            return true;
        }
        if (_isEmnpty(label)) {
            pass = false;
            openNotificationWithIcon("error", "", `节点 ${label} 名称未填写`);
            return true;
        }
        if (overrideList.indexOf(overrideid) !== -1 && !isGateway) {
            pass = false;
            openNotificationWithIcon("error", "", `节点 ${label} 编码重复`);
            return true;
        }
        overrideList.push(overrideid);

        if (shape === 'GroupTaskStart') {
            groupStart.push(item);
        } else if (shape === 'GroupTaskEnd') {
            groupEnd.push(item)
        }
        allProcesses[id] = item;
    })

    if (!pass) return false;

    if (groups.length > 0) {
        if (groupStart.length === 0 || groupEnd.length === 0) {
            openNotificationWithIcon("error", "", '子流程需要包含子流程开始节点和结束节点');
            pass = false;
        } else if (groupStart.length !== groupEnd.length) {
            openNotificationWithIcon("error", "", '子流程开始节点和结束节点数量应保持一致');
            pass = false;
        }
    }

    if (!pass) return false;

    groups.some(item => {
        const { model, id, label = '' } = item;
        const { properties } = model;
        const { overrideid } = properties;

        if (_isEmnpty(overrideid)) {
            pass = false;
            openNotificationWithIcon("error", "", `子流程 ${label} 编码未填写`);
            return true;
        }
        if (_isEmnpty(label)) {
            pass = false;
            openNotificationWithIcon("error", "", `子流程 ${label} 名称未填写`);
            return true;
        }
        if (overrideList.indexOf(overrideid) !== -1) {
            pass = false;
            openNotificationWithIcon("error", "", `子流程 ${label} 编码重复`);
            return true;
        }
        overrideList.push(overrideid);

        allProcesses[id] = item;
    })
    if (!pass) return false;

    const edgesSources = {};
    edges.forEach(item => {
        const { id, source } = item;

        const list = edgesSources[source] ?? [];
        list.push(item);

        allProcesses[id] = item;
        edgesSources[source] = list;
    })

    const circleBreak = {};
    groupStart.some(item => {
        pass = CheckConnection(circleBreak, allProcesses, edgesSources, item, item?.parent);
        if (!pass) {
            return true;
        }
    })

    return pass;
}


